import json
import re

from django import http
from django.core.cache import cache
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View

from areas.models import Area

from areas.models import Address
from utils.constants import USER_ADDRESS_COUNTS_LIMIT
from utils.response_code import RETCODE
from utils.views import LoginRequiredJsonMixin


# Create your views here.
class AreasView(LoginRequiredJsonMixin, View):
    def get(self, request):

        # 查出所有的市
        aread_id = request.GET.get("area_id")

        if not aread_id:  # 如果aread_id不存在、则将所有的省份查询出来并返回

            # 1、从redis数据库里查省份数据
            province_list = cache.get("province_list")
            print("redis获取到的province_list------->>>>", province_list)

            if not province_list:
                try:
                    data = Area.objects.filter(parent__isnull=True)

                    # 2、将查询出来的数据进行序列化
                    province_list = []
                    for i in data:
                        province_list.append({"id": i.id, "name": i.name})

                    # 3、设置redis缓存
                    cache.set("province_list", province_list, 3600)

                except Exception as e:
                    return JsonResponse({'code': RETCODE.DBERR, 'errmsg': '数据查询失败'})

            return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'province_list': province_list})

        else:  # 如果aread_id可以取出值、则返回对应的parent_id的市区
            # 1、从缓存里查询数据
            sub_data = cache.get("sub_area_%s" % aread_id)
            if not sub_data:
                try:
                    data = Area.objects.get(id=aread_id)
                    sub_all = data.subs.all()
                    # 2、将查询出来的数据序列化
                    sub_list = []
                    for i in sub_all:
                        sub_list.append({"id": i.id, "name": i.name})

                    sub_data = {
                        'id': data.id,  # 父级pk
                        'name': data.name,  # 父级的name
                        'subs': sub_list,  # 父级的name
                    }
                    # 将数据存储到redis缓存中
                    cache.set("sub_area_%s" % aread_id, sub_data, 3600)

                except Exception as e:
                    return JsonResponse({'code': RETCODE.DBERR, 'errmsg': '数据查询失败'})

            return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'sub_data': sub_data})


class AddressCreateView(LoginRequiredJsonMixin, View):
    def post(self, request):
        print("进入函数")
        add_count = request.user.addresses.count()
        if add_count >= USER_ADDRESS_COUNTS_LIMIT:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '超过地址数量上限'})

        # 1、获取参数
        json_dict = json.loads(request.body)
        receiver = json_dict.get("receiver")
        province_id = json_dict.get("province_id")
        city_id = json_dict.get("city_id")
        district_id = json_dict.get("district_id")
        place = json_dict.get("place")
        mobile = json_dict.get("mobile")
        tel = json_dict.get("tel")
        email = json_dict.get("email")
        print("获取到的值----->>>", receiver, province_id, city_id, district_id, place, mobile, tel, email)

        # 2、校验参数
        # 2.1 校验传入的参数是否有缺失
        print("通过验证1")
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '缺少必传参数'})
        # 2.2 校验手机号码格式是否正确
        print("通过验证2")
        if not re.match(r"^1[3-9]\d{9}$", mobile):
            return http.JsonResponse({'code': RETCODE.MOBILEERR, 'errmsg': '手机格式有误、请确认后再试'})
        # 2.3 校验输入的固定电话是否正确
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')

        # 2.4校验邮箱格式是否正确
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')

        # 3、存储数据
        try:
            add = Address.objects.create(
                user=request.user,
                title=receiver,
                receiver=receiver,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email,
                city_id=city_id,
                district_id=district_id,
                province_id=province_id,
            )
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '地址保存失败'})

        # 4、判断一下该用户是否已经存在默认地址
        if not request.user.default_address:
            # 4.1 如果不存在、则将刚保存的数据设置为默认地址
            try:
                default_id = request.user.default_address = add
            except Exception as e:
                return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '默认地址保存失败'})

        # 5、返回结果
        response = {
            "code": RETCODE.OK,
            "errmsg": "成功",
            "id": add.id,
            "title": add.title,
            "receiver": add.receiver,
            "province": add.province.name,
            "city": add.city.name,
            "district": add.district.name,
            "place": add.place,
            "mobile": add.mobile,
            "tel": add.tel,
            "email": add.email,
        }
        # 响应保存结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '新增地址成功', 'address': response})


class UpdateAddView(LoginRequiredJsonMixin, View):
    def put(self, request, add_id):
        # 校验一下要修改的用户是否与地址用户一致
        address = Address.objects.get(id=add_id)
        if not (address and address.user == request.user):
            return http.HttpResponseBadRequest('非法操作')

        # 1、获取参数
        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')
        print(json_dict, receiver, province_id, city_id, district_id, place, mobile, tel, email)

        # 2、校验参数
        # 校验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.HttpResponseBadRequest('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')

        print("通过校验")
        # 3、更新地址
        try:
            Address.objects.filter(id=add_id).update(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email
            )
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '更新地址失败'})
        # 将最新的收货地址查询出来、并返回
        add_user = Address.objects.get(id=add_id)
        address_dict = {
            "id": add_user.id,
            "title": add_user.title,
            "receiver": add_user.receiver,
            "province": add_user.province.name,
            "city": add_user.city.name,
            "district": add_user.district.name,
            "place": add_user.place,
            "mobile": add_user.mobile,
            "tel": add_user.tel,
            "email": add_user.email
        }

        # 响应更新地址结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '更新地址成功', 'address': address_dict})

    def delete(self, request, add_id):
        # 校验一下要修改的用户是否与地址用户一致
        address = Address.objects.get(id=add_id)
        if not (address and address.user == request.user):
            return http.HttpResponseBadRequest('非法操作')

        # 将is_delete设置为true
        try:
            address.is_deleted = True
            address.save()
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '删除地址失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除地址成功'})


class TitleView(LoginRequiredJsonMixin, View):
    def put(self, request, add_id):
        # 校验一下要修改的用户是否与地址用户一致
        address = Address.objects.get(id=add_id)
        if not (address and address.user == request.user):
            return http.HttpResponseBadRequest('非法操作')

        # 1、获取数据
        json_dict = json.loads(request.body)
        title = json_dict.get("title")

        # 2、存入数据库
        try:
            address.title = title
            address.save()
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '设置地址标题失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置地址标题成功'})


class DefaultView(LoginRequiredJsonMixin, View):
    def put(self, request, add_id):
        # 校验一下要修改的用户是否与地址用户一致
        address = Address.objects.get(id=add_id)
        if not (address and address.user == request.user):
            return http.HttpResponseBadRequest('非法操作')

        try:
            request.user.default_address_id = add_id
            request.user.save()
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '默认地址设置失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '成功'})
